package com.example.springstack.springsecurity.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.exampl.springstack.common.GlobalConst;
import com.exampl.springstack.common.utils.LocalCacheUtils;
import com.example.springstack.springsecurity.entity.AuthenticationInfoVo;
import com.example.springstack.springsecurity.entity.AuthorizationUser;
import com.example.springstack.springsecurity.service.JwtService;
import com.example.springstack.springsecurity.service.UserService;
import com.nimbusds.oauth2.sdk.util.OrderedJSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Qiangfanghao
 * 自定义登录校验service
 */
@Service("loginService")
@Slf4j
public class LoginServiceImpl {

    @Autowired
    private PasswordEncoder pw;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private JwtService jwtService;

    public AuthenticationInfoVo login(AuthorizationUser authorizationUser, HttpServletRequest request) {
        JSONObject jsonObject = new JSONObject();
        try {
            //user 校验 用户名 + 密码校验
            UserDetails userDetails = userService.loadUserByUsername(authorizationUser.getUsername());
            //matches 第一个参数明文 第二个参数 密文
            if( !pw.matches(authorizationUser.getPassword(),userDetails.getPassword())){
                throw new UsernameNotFoundException("用户名密码错误");
            }
            //当前登录用户username
            String currentUserName = userDetails.getUsername();

            //根据username 生成 pe系统的 token
            String jwtCurrentIp = jwtService.getJwtCurrentIp(request);
            AuthenticationInfoVo authenticationInfoVo = jwtService.jwtBuild(userDetails.getUsername(), jwtCurrentIp);

            //获取之前使用的token
            Object oldTokenObj = LocalCacheUtils.get(currentUserName + GlobalConst.CURRENT_SYSUSER_TOKEN_KEY);

            //将 新token 存在本地缓存 默认存储 1个小时
            LocalCacheUtils.push(currentUserName + GlobalConst.CURRENT_SYSUSER_TOKEN_KEY,authenticationInfoVo.getToken());
            //将 新token存入 本地缓存
            LocalCacheUtils.push(authenticationInfoVo.getToken(),userDetails);

            //清理之前使用的token 对应的用户信息 保证每次都有一个token 对应的用户 在缓存中
            if (oldTokenObj != null){
                String oldToken = String.valueOf(oldTokenObj);
                LocalCacheUtils.remove(oldToken);
            }

            return authenticationInfoVo;
        } catch (Exception e) {
            log.error("【LoginServiceImpl:login】登录接口异常={}", e.getMessage(), e);
        }
        return null;
    }
}
